package com.zzyl.serve.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzyl.common.exception.BusinessException;
import com.zzyl.common.utils.DateUtils;
import com.zzyl.serve.domain.NursingLevel;
import com.zzyl.serve.domain.NursingPlan;
import com.zzyl.serve.mapper.NursingLevelMapper;
import com.zzyl.serve.service.INursingLevelService;
import com.zzyl.serve.service.INursingPlanService; // 新增：导入护理计划Service
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 护理等级Service业务层处理（补充护理计划关联逻辑）
 *
 * @author ruoyi
 * @date 2024-10-04
 */
@Service
public class NursingLevelServiceImpl extends ServiceImpl<NursingLevelMapper, NursingLevel> implements INursingLevelService
{
    @Autowired
    private NursingLevelMapper nursingLevelMapper;

    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    // 新增：注入护理计划Service，用于关联校验和查询
    @Autowired
    private INursingPlanService nursingPlanService;

    private static final String CACHE_KEY_PREFIX = "nursingLevel:all";

    /**
     * 查询护理等级（补充关联的护理计划信息）
     *
     * @param id 护理等级主键
     * @return 护理等级（含关联的护理计划信息）
     */
    @Override
    public NursingLevel selectNursingLevelById(Long id) {
        NursingLevel nursingLevel = getById(id);
        if (nursingLevel == null) {
            return null;
        }
        NursingPlan plan = nursingPlanService.getById(nursingLevel.getLplanId());
        if (plan != null) {
            // 若需要在返回结果中携带护理计划名称，可在NursingLevel中新增字段或用VO
            nursingLevel.setLplanName(plan.getPlanName());
        }
        return nursingLevel;
    }

    /**
     * 查询护理等级列表（补充关联的护理计划信息）
     *
     * @param nursingLevel 查询条件
     * @return 护理等级列表（含关联的护理计划信息）
     */
    @Override
    public List<NursingLevel> selectNursingLevelList(NursingLevel nursingLevel) {
        // 查询护理等级列表
        List<NursingLevel> levelList = nursingLevelMapper.selectNursingLevelList(nursingLevel);

        // 遍历列表，为每个护理等级对象设置关联的护理计划名称
        levelList.forEach(level -> {
            NursingPlan plan = nursingPlanService.getById(level.getLplanId());
            if (plan != null) {
                level.setLplanName(plan.getPlanName());
                System.out.println("护理计划名称：" + plan.getPlanName());
            }
        });
        return levelList;
    }

    /**
     * 新增护理等级（校验关联的护理计划是否存在）
     *
     * @param nursingLevel 护理等级
     * @return 结果
     */
    @Override
    public int insertNursingLevel(NursingLevel nursingLevel) throws BusinessException {
        // 新增：校验关联的护理计划必须存在
        Long lplanId = nursingLevel.getLplanId();
        if (lplanId == null) {
            throw new BusinessException("护理计划ID不能为空");
        }
        NursingPlan plan = nursingPlanService.getById(lplanId);
        if (plan == null) {
            throw new BusinessException("关联的护理计划不存在，请先创建护理计划");
        }

        nursingLevel.setCreateTime(DateUtils.getNowDate());
        boolean fl = this.save(nursingLevel);
        deleteCache();
        return fl ? 1 : 0;
    }

    /**
     * 删除缓存
     */
    private void deleteCache() {
        redisTemplate.delete(CACHE_KEY_PREFIX);
    }

    /**
     * 修改护理等级（校验关联的护理计划是否存在）
     *
     * @param nursingLevel 护理等级
     * @return 结果
     */
    @Override
    public int updateNursingLevel(NursingLevel nursingLevel) throws BusinessException {
        // 新增：若修改了护理计划ID，校验新关联的护理计划是否存在
        Long lplanId = nursingLevel.getLplanId();
        if (lplanId != null) {
            NursingPlan plan = nursingPlanService.getById(lplanId);
            if (plan == null) {
                throw new BusinessException("关联的护理计划不存在，请先创建护理计划");
            }
        }

        nursingLevel.setUpdateTime(DateUtils.getNowDate());
        boolean flag = this.updateById(nursingLevel);
        deleteCache();
        return flag ? 1 : 0;
    }

    /**
     * 删除护理等级信息（保持原逻辑，已处理启用状态校验）
     */
    @Override
    public int deleteNursingLevelById(Long id) throws BusinessException {
        NursingLevel nursingLevel = this.getById(id);
        if (nursingLevel == null) {
            return 0;
        }
        if (nursingLevel.getStatus() == 1) {
            throw new BusinessException("启用中的护理等级，不能删除");
        }
        deleteCache();
        return this.removeById(id) ? 1 : 0;
    }

    /**
     * 查询所有护理等级列表（补充关联的护理计划信息）
     */
    @Override
    public List<NursingLevel> getLevelAll() {
        // 1. 先从Redis缓存获取
        List<NursingLevel> list = (List<NursingLevel>) redisTemplate.opsForValue().get(CACHE_KEY_PREFIX);
        // 缓存命中，直接返回
        if (list != null && !list.isEmpty()) {
            return list;
        }

        // 2. 缓存未命中，从数据库查询启用状态（status=1）的护理等级
        list = nursingLevelMapper.selectList(Wrappers.<NursingLevel>lambdaQuery()
                .eq(NursingLevel::getStatus, 1));

        // 3. 存入Redis缓存，供下次查询使用
        redisTemplate.opsForValue().set(CACHE_KEY_PREFIX, list);

        return list;
    }
}